import { reqLogin, reqLogout, reqGetUserInfo } from '@/api/user'
import { getToken, setToken, removeToken } from '@/utils/auth'
import { resetRouter } from '@/router'
import { constantRoutes, allAsyncRoutes, anyRoute } from '@/router'
import { cloneDeep } from 'lodash'
import router from '@/router'


// 过滤出权限的路由
function filterRoutes(routeName, allRoutes) {
  return allRoutes.filter(route => {
    //  判断是否包含路由 有就返回
    if (!routeName.includes(route.name)) return false

    // 如果有子路由  且 子路由最少存在一个时 进行递归调用
    if (route.children && route.children.length > 0) {
      route.children = filterRoutes(routeName, route.children)
    }

    // 返回有权限的路由
    return true
  })
}

const getDefaultState = () => {
  return {
    token: getToken() || ``,
    name: '',
    avatar: '',
    routes: constantRoutes,
    buttons: []
  }
}

const state = getDefaultState()

const mutations = {
  RESET_STATE: (state) => {
    Object.assign(state, getDefaultState())
  },
  SET_TOKEN: (state, token) => {
    state.token = token
  },
  SET_NAME: (state, name) => {
    state.name = name
  },
  SET_AVATAR: (state, avatar) => {
    state.avatar = avatar
  },
  SET_Routes: (state, routes) => {
    state.routes = routes
  },
  SET_Buttons: (state, buttons) => {
    state.buttons = buttons
  }
}

const actions = {
  // user login
  async login({ commit }, userInfo) {

    const { username, password } = userInfo
    // console.log(username, password);

    const result = await reqLogin({ username: username.trim(), password: password.trim() })
    // 获取token
    const { data } = result;
    // 将token保存在vuex中
    commit('SET_TOKEN', data.token)
    // 本地存储token
    setToken(data.token)
    console.log(result);
  },

  // get user info
  getInfo({ commit }) {
    return new Promise((resolve, reject) => {
      // 重新封装api  新的api中不需要传入token 参数
      reqGetUserInfo().then(response => {
        const { data } = response

        if (!data) {
          return reject('Verification failed, please Login again.')
        }
        console.log(data);
        const { name, avatar, routes, buttons } = data
        // 过滤后权限的路由               bug： 如果使用的原来的所有异步路由，当页面无刷的时候先登录普通用户再登录admin管理员用户，这时admin管理员的路由也只有普通用户的路由权限 所以我们需要拷贝一份异步路由用于过滤
        const asyncRoutes = filterRoutes(routes, cloneDeep(allAsyncRoutes))
        // 将权限路由和静态路由结合 重新赋值给routes
        const newRoutes = constantRoutes.concat(asyncRoutes)
        console.log(newRoutes);
        // 添加映射关系
        router.addRoutes([...newRoutes, anyRoute])
        commit('SET_Routes', newRoutes)
        commit('SET_NAME', name)
        commit('SET_AVATAR', avatar)
        commit('SET_Buttons', buttons)
        resolve(data)
      }).catch(error => {
        reject(error)
      })
    })
  },

  // user logout
  logout({ commit, state }) {
    return new Promise((resolve, reject) => {
      reqLogout(state.token).then(() => {
        removeToken() // must remove  token  first
        resetRouter()
        commit('RESET_STATE')
        resolve()
      }).catch(error => {
        reject(error)
      })
    })
  },

  // remove token
  resetToken({ commit }) {
    return new Promise(resolve => {
      removeToken() // must remove  token  first
      commit('RESET_STATE')
      resolve()
    })
  }
}

export default {
  namespaced: true,
  state,
  mutations,
  actions
}
